﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using MindFactorial.LaunchPoint.Runtime;
using MindFactorial.LaunchPoint.Console.Library;
using MindFactorial.LaunchPoint.Common;

namespace MindFactorial.LaunchPoint.Console
{
    /// <summary>
    /// Interaction logic for ConsoleWindow.xaml
    /// </summary>
    public partial class ConsoleWindow : IRootWindow
    {
        StartupApplication _startupApp;
        ImageBrush _maximizedButton = null;
        ImageBrush _unMaximizedButton = null;
        PluginMessagingPipeline _pipeline = null;
        Dictionary<string,ConsoleShell> _shells = null;
        ConsoleShell _currentShell = null;
        LaunchPad  _launchpad = null;
        LoginPage _login = null;
        string _user_id = null;
        

        public ConsoleWindow(StartupApplication startupApp)
        {
            InitializeComponent();
            this._startupApp = startupApp;
            _pipeline = new PluginMessagingPipeline(this);
            _shells = new Dictionary<string,ConsoleShell>();
            _launchpad = new LaunchPad(this);
            _login = new LoginPage(this);

            _maximizedButton = (ImageBrush)Resources.MergedDictionaries[0]["MaximizedButton"];
            _unMaximizedButton = (ImageBrush)Resources.MergedDictionaries[0]["UnMaximizedButton"];
            
            
            //handle closing event
            this.Closing += delegate(object sender, System.ComponentModel.CancelEventArgs e)
            {
                PipelineBroadcastEvent(null, "/console/close", "close");
            };      


            this.labelConsole.MouseDown += delegate(object sender, MouseButtonEventArgs e)
            {
                if (e.ChangedButton == MouseButton.Left)
                    this.DragMove();
            };

            this.imageMinimizeButton.MouseDown += delegate(object sender, MouseButtonEventArgs e)
            {
                this.WindowState = WindowState.Minimized;
            };

            this.imageCloseButton.MouseDown += delegate(object sender, MouseButtonEventArgs e)
            {
                //foreach (ConsolePlugIn plugin in _plugins.Values)
                //{
                //    plugin.ShutDown();
                //}
                this.Close();
            };

            this.imageMaximizeButton.MouseDown += delegate(object sender, MouseButtonEventArgs e)
            {
                if (this.WindowState == WindowState.Normal)
                {
                    this.imageMaximizeButton.Source = _maximizedButton.ImageSource;
                    //this.imageMaximizeButton == this.imageMaximizeButton2;
                    this.WindowState = WindowState.Maximized;

                }
                else
                {
                    this.imageMaximizeButton.Source = _unMaximizedButton.ImageSource;
                    //this.imageMaximizeButton.Source = "maximizeButtonOn.png"; 
                    this.WindowState = WindowState.Normal;
                }
            };

            this.labelConsole.MouseDoubleClick += delegate(object sender, MouseButtonEventArgs e)
            {
                if (this.WindowState == WindowState.Normal)
                {
                    this.imageMaximizeButton.Source = _maximizedButton.ImageSource;
                    //this.imageMaximizeButton == this.imageMaximizeButton2;
                    this.WindowState = WindowState.Maximized;

                }
                else
                {
                    this.imageMaximizeButton.Source = _unMaximizedButton.ImageSource;
                    //this.imageMaximizeButton.Source = "maximizeButtonOn.png"; 
                    this.WindowState = WindowState.Normal;
                }
            };

            this.waitUI.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e)
            {
                this.DragMove();
            };
            
            
            this.PreviewKeyDown += delegate(object sender, KeyEventArgs args)
            {
                if (!appbrowser.IsKeyboardFocusWithin)
                {
                    if (args.Key == Key.Back)
                    {
                        args.Handled = true;
                    }
                }
            };

            
            appbrowser.Navigate(_login);
        }

        

        internal void SetCurrentUser(string user_id)
        {
            this._user_id = user_id;
        }

        internal void SetLanguage(string language_id)
        {
            System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language_id);
        }

        /// <summary>
        /// adds a new consoleshell (complete with all plugins) to
        /// the list of available shells of the window
        /// </summary>
        /// <param name="shell"></param>
        internal void AddPluginShell(string pluginname, ConsoleShell shell)
        {
            _shells.Add(pluginname, shell);
        }
        
        /// <summary>
        /// navigates to the first consoleshell in the shell list
        /// </summary>
        internal void NavigateToFirstPlugin()
        {
            ConsoleShell shell = null;
            foreach (ConsoleShell item in _shells.Values)
            {
                shell = item;
                break;
            }
            if (shell != null)
            {
                _currentShell = shell;
                appbrowser.Navigate(shell);
            }
            else
            {
                Logger.Log("AF6C19A3-654A-47ce-AA90-4D54FA03722A: No plugin shells to load.");
                MessageBox.Show("AF6C19A3-654A-47ce-AA90-4D54FA03722A: No plugin shells to load.");
            }
        }

        internal void NavigateToPlugin(string pluginName)
        {
            if (_shells.ContainsKey(pluginName))
            {
                ConsoleShell pluginshell = _shells[pluginName];
                _currentShell = pluginshell;
                appbrowser.Navigate(pluginshell);
            }
            else
            {
                MessageBox.Show("Comming Soon...");
            }
        }

        /// <summary>
        /// navigates to the launchpad
        /// </summary>
        internal void NavigateToLaunchpad()
        {
            appbrowser.Navigate(_launchpad);
        }

        /// <summary>
        /// Gets the curently logged in user
        /// </summary>
        public string CurrentUser
        {
            get
            {
                return _user_id;
            }
        }

        /// <summary>
        /// gets or sets the window title
        /// </summary>
        internal string WindowTitle
        {
            get
            {
                return this.labelConsole.Content.ToString();
            }
            set
            {
                this.labelConsole.Content = string.Format("{0} {1} - {2}",Properties.Resources.MAIN_CONSOLE_TITLE,Properties.Resources.Console_Version, value);
                this.Title = (string)this.labelConsole.Content;
            }
        }

        public void UnloadCurrentPlugin()
        {
            string targetPluginName = _currentShell.CurrentPlugin.Name;
           // bool previousReached = false;
            //ConsoleShell previous = null;

            foreach (ConsoleShell shell in _shells.Values)
            {
                //remove this name from each shell's list of plugin

                //if I am at the plugin that i want removed then i know the last plugin 
                //i was at IS the previous plugin in that case stop assigning to previous
                //if (shell.CurrentPlugin.Name == targetPluginName)
                //{
                //    previousReached = true;
                //}

                ////if the previous has not been reached keep assigning to previous
                //if (!previousReached)
                //{
                //    previous = shell;
                //}

                shell.UnRegisterPlugin(targetPluginName);
            }
            _shells.Remove(targetPluginName);

            if (_shells.Count > 0)
            {
                ConsoleShell target = null;
                foreach (ConsoleShell shell in _shells.Values)
                {
                    target = shell;
                    break;
                }
                NavigateToPlugin(target.CurrentPlugin.Name);
            
            }

            //once everything is removed, navigate to the appropriate plugin
            
        }


        internal void StartWaiting()
        {
            this.waitUI.Visibility = Visibility.Visible;
        }

        internal void StopWaiting()
        {
            CrossThreadDelegate ctd = delegate()
            {
                this.waitUI.Visibility = Visibility.Collapsed;
            };
            this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, ctd);
        }

        public void PipelineBroadcastEvent(string application, string filter, string message)
        {
            if(_currentShell != null)
                _currentShell.PipelineBroadcastEvent(application, filter, message);
        }


        #region IRootWindow Members

        public PluginMessagingPipeline MessagingPipeline
        {
            get { return _pipeline; }
        }

        public LaunchPointApplication RunnableContext
        {
            get { return _startupApp; }
        }

        #endregion
    }
}
